<template>
  <div class="containers">
    <div class="canvas" ref="canvas"></div>
    <div id="js-properties-panel" class="panel"></div>
    <div class="inputs">
      <el-input type="text" v-model="name" placeholder="请输入流程图的名称"></el-input>
    </div>
    <!-- <div class="buttons1">
      <el-button type="primary" @click="save">保存</el-button>
    </div>-->
    <ul class="buttons">
      <!-- <li>下载</li> -->
      <!-- <li>
        <a ref="saveDiagram" href="javascript:" title="download BPMN diagram">保存到本地</a>
      </li> -->
      <li>
        <el-button type="primary" @click="save">保存</el-button>
      </li>
      <!-- <li>
        <a ref="saveSvg" href="javascript:" title="download as SVG image">保存为SVG</a>
      </li>-->
      <li>
        <el-upload class="upload-demo" action :http-request="uploadfile" :show-file-list="false">
          <el-button type="primary">上传文件</el-button>
        </el-upload>
      </li>
    </ul>
    <el-upload
      class="avatar-uploader"
      action
      :http-request="designUpAvatar3"
      :show-file-list="false"
    >
      <img v-if="imgshow" :src="imgshow" class="avatar" />
      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
  </div>
</template>

<script>
// 引入相关的依赖
import jq from 'jquery'
import { uploadFile, addPeople, getPeople, updatePeople } from "@/api/people";
import { addliuchengtu, writeliuchengtu } from "@/api/bumen";
import BpmnModeler from "bpmn-js/lib/Modeler";
import BpmnViewer from "bpmn-js";
import propertiesPanelModule from "bpmn-js-properties-panel";
import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
import customTranslate from "./customTranslate/customTranslate";
import router from '@/router'
// import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
//import { xmlStr } from "../mock/xmlStr"; // 这里是直接引用了xml字符串
let parentid = null,
  selfid = null;
let tempstr = ''
export default {
  name: "",
  components: {},
  // 生命周期 - 创建完成（可以访问当前this实例）
  created() {},
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null,
      xmlStr: null,
      name: "",
      isWrite: false,
      currentElement: "",
      domId: "",
      imglist: [],
      imgshow: "",
      fileId: ""
    };
  },
  // 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成，一般在该过程进行 Ajax 交互
  mounted() {
    console.log("this.$route.params.isWrite", this.$route.params.isWrite);
    const lct = localStorage.getItem("lct");
    if (lct) {
      const temp = JSON.parse(lct);
      tempstr = temp.fileContents;
      parentid = temp.parentId;
      selfid = temp.id;
      this.name = temp.name;
      this.isWrite = true;
    } else {
      parentid = this.$route.params.options;
      tempstr = `<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" targetNamespace="http://bpmn.io/bpmn" exporter="bpmn-js (https://demo.bpmn.io)" exporterVersion="5.1.2">
<process id="Process_1" isExecutable="false">
<startEvent id="StartEvent_1y45yut" name="开始">
<outgoing>SequenceFlow_0h21x7r</outgoing>
</startEvent>
</process>
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
    <bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
    <bpmndi:BPMNShape id="StartEvent_1y45yut_di" bpmnElement="StartEvent_1y45yut">
        <omgdc:Bounds x="152" y="102" width="36" height="36" />
        <bpmndi:BPMNLabel>
        <omgdc:Bounds x="160" y="145" width="22" height="14" />
        </bpmndi:BPMNLabel>
    </bpmndi:BPMNShape>
    <bpmndi:BPMNShape id="Task_1hcentk_di" bpmnElement="Task_1hcentk">
        <omgdc:Bounds x="240" y="80" width="100" height="80" />
    </bpmndi:BPMNShape>
    <bpmndi:BPMNEdge id="SequenceFlow_0h21x7r_di" bpmnElement="SequenceFlow_0h21x7r">
        <omgdi:waypoint x="188" y="120" />
        <omgdi:waypoint x="240" y="120" />
    </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>`;
      console.log("parentid", parentid);
    }
    // if(this.$route.params.isWrite){

    // }else{

    // }
    this.init();
    let _this = this;
    // 获取a标签dom节点
    const downloadLink = this.$refs.saveDiagram;
    const downloadSvgLink = this.$refs.saveSvg;
    // 给图绑定事件，当图有发生改变就会触发这个事件
    this.bpmnModeler.on("commandStack.changed", function() {
      _this.saveSVG(function(err, svg) {
        _this.setEncoded(downloadSvgLink, "diagram.svg", err ? null : svg);
      });
      _this.saveDiagram(function(err, xml) {
        console.log("保存事件");
        _this.setEncoded(downloadLink, "diagram.bpmn", err ? null : xml);
      });
    });
    this.createNewDiagram(this.bpmnModeler);
    // document.querySelector('#camunda-documentation').contentEditable = false
    const eventBus = this.bpmnModeler.get("eventBus");
    // 注册节点事件，eventTypes中可以写多个事件
    const eventTypes = ["element.click", "element.hover"];
    eventTypes.forEach(eventType => {
      eventBus.on(eventType, this.debounce(e => {  
        const { element } = e;
        // console.log(e)
        if (!element.parent) return;
        if (!e || element.type === "bpmn:Process") {
          return false;
        } else {
          if (eventType === "element.click") {
            // 节点点击后想要做的处理
            // 此时想要点击节点后，拿到节点实例，通过外部输入更新节点名称
            console.log("鼠标点击le节点");
            console.log(element);
            this.domId = element.id;
            // this.$router.push({
            //   name: 'Editorliucheng',
            //   params: {
            //     nodeId: element.id
            //   }
            // })
            this.currentElement = element;
            this.getimg(element.id).then(res => {
              console.log("回调结果", res);
              if (res.data.list.length != 0) {
                this.imgshow = res.data.list[0].fileName;
                this.fileId = res.data.list[0].fileId;
              } else {
                this.imgshow = "";
              }
            });
            // 点击节点查找对应id得图片没有得话设为空
          } else if (eventType === "element.hover") {
            // 鼠标滑过节点后想要做的处理
            console.log("鼠标经过节点啦~");
          }
        }
      },1000));
    })
    
  },
  methods: {
    init() {
      // 初始化汉化
      let customTranslateModule = {
        translate: ["value", customTranslate]
      };
      // 获取到属性ref为“canvas”的dom节点
      const canvas1 = this.$refs.canvas;
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas1,
        propertiesPanel: {
          parent: "#js-properties-panel"
        },
        additionalModules: [
          // 左边工具栏以及节点
          propertiesProviderModule,
          // 右边的工具栏
          propertiesPanelModule,
          // 汉化
          customTranslateModule
        ]
      });
      this.createNewDiagram(tempstr);
    },
    // 创建流程图
    createNewDiagram(value) {
      // 将字符串转换成图显示出来
      this.bpmnModeler.importXML(value, err => {
        if (err) {
          // console.error(err)
        } else {
          // 这里是成功之后的回调, 可以在这里做一系列事情
          this.success();
          this.setNodeColor()
        }
      });
    },
    success() {
      console.log("创建成功!");
    },
    setNodeColor() {
      // 目的：为第一个节点添加绿色，为第二个节点添加黄色
      // 实现步骤：1、找到页面里所有节点
      this.svgLine(jq('.djs-frame'))
      // const elementRegistry = this.bpmnModeler.get("elementRegistry");
      // console.log('elementRegistry',elementRegistry)
      // let nodeList = elementRegistry.filter(item =>
      //   item.type === 'bpmn:Group'
      // );
      // 此时得到的userTaskList 便是流程图中所有的节点的集合
      // console.log(nodeList);
      // 步骤2 ：为节点添加颜色
      // 方式1 ：modeling.setColor(参数1：节点，可以是单个元素实例，也可是多个节点组成的数组，参数2：class类);
      // let modeling = this.bpmnModeler.get("modeling");
      // let color = "#000000"
      // for(let i = 0;i<nodeList.length;i++){
      //   modeling.setColor(nodeList[i], {
      //     'stroke': color,
      //     'fill': 'none',
      //     'fill-rule': 'nonzero'
      //   });
      //   modeling.updateProperties(nodeList[i],{color: color})
      // }
      
    },
    /**
     * 绘制线条
     */
    svgLine(domlist){
      for(let i = 0;i<domlist.length;i++){
        console.log('每个节点')
        console.log(domlist.eq(i).children('.djs-visual').children()[0].attributes.width.nodeValue)
        let linewidth = domlist.eq(i).children('.djs-visual').children()[0].attributes.width.nodeValue
        // let demo = domlist.eq(i).children('.djs-visual').children()
        let innerhtml = domlist.eq(i).children('.djs-visual')[0].innerHTML
        // console.log(innerhtml)
        let copyinnerhtml = `<line x1="0" y1="30" x2="${linewidth}" y2="30" style="stroke:rgb(0,0,0);stroke-width:1" />`
        console.log(innerhtml+copyinnerhtml)
        console.log(domlist.eq(i).children('.djs-visual').html())
        domlist.eq(i).children('.djs-visual').html(innerhtml+copyinnerhtml)
        // console.log(innerhtml,typeof innerhtml)
      }
    },
    // 下载为SVG格式,done是个函数，调用的时候传入的
    saveSVG(done) {
      // 把传入的done再传给bpmn原型的saveSVG函数调用
      this.bpmnModeler.saveSVG(done);
    },
    // 下载为bpmn格式,done是个函数，调用的时候传入的
    saveDiagram(done) {
      console.log("保存为bpmn");
      // 把传入的done再传给bpmn原型的saveXML函数调用
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
        done(err, xml);
      });
    },
    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(link, name, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data);
      // 获取到图的xml，保存就是把这个xml提交给后台(可以在这一步提交后台)
      this.xmlStr = data;
      // console.log("encodedData", encodedData);
      // console.log("xmlStr", data);
      console.log(typeof data);
      // this.setNodeColor()
      // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
      if (data) {
        link.className = "active";
        link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
        link.download = name;
      }
    },
    // 点击节点获取图片信息
    getimg(id) {
      return getPeople({
        fileDescribe: id
      }).then(res => {
        console.log(res);
        return new Promise(resolve => {
          resolve(res);
        });
      });
    },
    // 保存上传服务器
    save() {
      if (this.name) {
        const user = this.$store.state.user.userInfo[0];
        this.xmlStr = this.xmlStr || tempstr
        tempstr = this.xmlStr
        console.log(this.xmlStr)
        if (this.isWrite) {
          writeliuchengtu({
            persons: user.username,
            departments: user.departments,
            fileContents: this.xmlStr,
            parentId: parentid,
            id: selfid,
            name: this.name
          }).then(res => {
            console.log(res);
            this.$message({
              message: "修改成功！",
              type: "success"
            });
            this.$router.go(-1);
          });
        } else {
          addliuchengtu({
            persons: user.username,
            departments: user.departments,
            fileContents: this.xmlStr,
            parentId: parentid,
            name: this.name
          }).then(res => {
            console.log(res);
            this.$message({
              message: "保存成功！",
              type: "success"
            });
            this.$router.go(-1);
          });
        }
      } else {
        this.$message({
          message: "请先输入流程图名称",
          type: "warning"
        });
      }
    },
    // 导入文件（后续可以设置成上传到服务器，从服务器请求到，重新渲染，从而达到部门查看流程图功能）
    importFile(file) {
      const reader = new FileReader();
      // 读取File对象中的文本信息，编码格式为UTF-8
      reader.readAsText(file, "utf-8");
      reader.onload = () => {
        console.log(reader.result);
        //读取完毕后将文本信息导入到Bpmn建模器
        this.createNewDiagram(reader.result);
      };
      return false;
    },
    // 上传文件
    uploadfile(item) {
      if (this.name) {
        var formData = new FormData();
        formData.append("file", item.file);
        uploadFile(formData).then(res => {
          console.log(res);
          addPeople({
            fileName: res,
            fileDescribe: this.name
          }).then(result => {
            console.log(result);
            this.$message({
              showClose: true,
              message: "添加成功",
              type: "success"
            });
          });
        });
      } else {
        this.$message({
          message: "请先输入流程图名称",
          type: "warning"
        });
      }
    },
    // 上传图片详情
    designUpAvatar3(item) {
      var formData = new FormData();
      formData.append("file", item.file);
      uploadFile(formData).then(res => {
        console.log(res);
        // 如果上传图片时候有img,说明之前有图片,进行修改操作
        if (this.imgshow) {
          console.log("修改");
          this.imgshow = res;
          updatePeople({
            fileName: res,
            fileDescribe: this.domId,
            fileId: this.fileId
          }).then(result => {
            console.log(result);
            this.$message({
              showClose: true,
              message: "修改成功",
              type: "success"
            });
          });
          // 判断是否在未刷新情况下
          // const tempindex = this.imglist.findIndex(list => list.id == this.domId)
          // if(tempindex != -1){
          //   this.imglist.splice(tempindex,1)
          //   this.imglist.push({
          //     path: res,
          //     id: this.domId
          //   })
          // }
        } else {
          // 如果上传图片时候没有img,进行新增操作
          this.imgshow = res;
          console.log("新增");
          addPeople({
            fileName: res,
            fileDescribe: this.domId
          }).then(result => {
            console.log(result);
            this.$message({
              showClose: true,
              message: "添加成功",
              type: "success"
            });
          });
          // this.imglist.push({
          //   path: res,
          //   id: this.domId
          // })
        }
        // this.imageUrl = res
        this.$forceUpdate();
      });
    }
  },
  beforeRouteLeave (to, from, next) {
    console.log('路由守卫')
    console.log(this.xmlStr,tempstr)
    console.log(this.xmlStr == tempstr)
    if(!this.xmlStr || tempstr === this.xmlStr){
      next()
    }else{
      const answer = window.confirm('您还没有保存更改，确定要离开吗？')
      if (answer) {
        next()
      } else {
        next(false)
      }
    }
  }
  
};
</script>

<style scoped lang="scss">
.inputs {
  width: 200px;
  position: absolute;
  top: 20px;
  left: 30px;
}
/deep/.djs-shape .djs-visual path{
  fill: none  !important;
  stroke-width: 0px !important;
  stroke: black;
}
.highlight-overlay {
  opacity: 0.3 !important;
  border-radius: 10px 10px 0 0 !important;
  background: #000 !important;
}
/deep/.djs-visual rect {
  stroke-dasharray: 0 !important;
  fill-rule: evenodd
}
/deep/.djs-visual text {
  // font-size: 14px !important;
  font-family: "Microsoft YaHei" !important;
  font-weight: bold !important;
}
/deep/.avatar-uploader .el-upload {
  border: 1px dashed #999 !important;
  border-radius: 6px;
  cursor: pointer;
  position: fixed;
  right: 190px;
  bottom: 10px;
  overflow: hidden;
  // width: 100%;
}
/deep/.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

/deep/.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
  // border: 1px solid #ccc;
}
/deep/.avatar {
  width: 100px;
  height: 100px;
  display: block;
}
.containers {
  position: absolute;
  background-color: #ffffff;
  color: #333;
  padding: 20px;
  box-sizing: border-box;
  width: 100%;
  height: 92%;
  top: 60px;
  left: 0;
}
/deep/.bpp-properties-panel {
  background-color: #f8f8f8;
  position: relative;
  height: 100%;
}
/deep/.bpp-properties-header {
  display: none;
  height: 100%;
}
/deep/.bpp-properties-tab-bar {
  display: none;
}
/deep/.bpp-textfield {
  display: none;
}
/deep/.group-label {
  display: none;
}
/deep/.djs-palette {
  position: absolute;
  left: 10px;
  top: 60px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}
.canvas {
  width: 100%;
  height: 100%;
}
.panel {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
  height: 100%;
  overflow-y: auto;
}
.buttons {
  position: absolute;
  left: -10px;
  bottom: 10px;
  & > li {
    display: inline-block;
    margin: 5px;
    position: relative;
    & > a {
      color: #999;
      background: #eee;
      // cursor: not-allowed;
      padding: 8px;
      border: 1px solid #ccc;
      &.active {
        color: #333;
        background: #fff;
        cursor: pointer;
      }
    }
  }
}
</style>